package vaccine.appointment.system.statistics.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import vaccine.appointment.system.appointmentrecord.dataobject.AppointmentRecord;
import vaccine.appointment.system.appointmentrecord.enums.AppointmentStatusEnum;
import vaccine.appointment.system.appointmentrecord.mapper.AppointmentRecordMapper;
import vaccine.appointment.system.common.enums.DelFlgEnum;
import vaccine.appointment.system.common.errorcode.CommonErrorCode;
import vaccine.appointment.system.common.exception.CommonException;
import vaccine.appointment.system.inventory.dataobject.Inventory;
import vaccine.appointment.system.inventory.mapper.InventoryMapper;
import vaccine.appointment.system.statistics.service.StatisticsService;
import vaccine.appointment.system.statistics.vo.AppointmentTrendVO;
import vaccine.appointment.system.statistics.vo.SiteStatisticsVO;
import vaccine.appointment.system.statistics.vo.SystemOverviewVO;
import vaccine.appointment.system.user.dataobject.User;
import vaccine.appointment.system.user.enums.IdentityInfoEnum;
import vaccine.appointment.system.user.mapper.UserMapper;
import vaccine.appointment.system.vaccinationsite.dataobject.VaccinationSite;
import vaccine.appointment.system.vaccinationsite.mapper.VaccinationSiteMapper;
import vaccine.appointment.system.vaccine.dataobject.Vaccine;
import vaccine.appointment.system.vaccine.mapper.VaccineMapper;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 统计服务实现类
 */
@Service
public class StatisticsServiceImpl implements StatisticsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AppointmentRecordMapper appointmentRecordMapper;

    @Autowired
    private VaccinationSiteMapper vaccinationSiteMapper;

    @Autowired
    private VaccineMapper vaccineMapper;

    @Autowired
    private InventoryMapper inventoryMapper;

    /**
     * 获取系统概览统计
     */
    @Override
    public SystemOverviewVO getSystemOverview() {
        SystemOverviewVO vo = new SystemOverviewVO();

        // 1. 统计总用户数（普通用户）
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("identity_info", IdentityInfoEnum.NORMAL_USER.getCode());
        userQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long totalUsers = userMapper.selectCount(userQueryWrapper);
        vo.setTotalUsers(totalUsers);

        // 2. 统计总预约数
        QueryWrapper<AppointmentRecord> appointmentQueryWrapper = new QueryWrapper<>();
        appointmentQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long totalAppointments = appointmentRecordMapper.selectCount(appointmentQueryWrapper);
        vo.setTotalAppointments(totalAppointments);

        // 3. 统计待接种预约数
        QueryWrapper<AppointmentRecord> pendingQueryWrapper = new QueryWrapper<>();
        pendingQueryWrapper.eq("appointment_status", AppointmentStatusEnum.APPOINTED.getCode());
        pendingQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long pendingAppointments = appointmentRecordMapper.selectCount(pendingQueryWrapper);
        vo.setPendingAppointments(pendingAppointments);

        // 4. 统计已完成预约数
        QueryWrapper<AppointmentRecord> completedQueryWrapper = new QueryWrapper<>();
        completedQueryWrapper.eq("appointment_status", AppointmentStatusEnum.COMPLETED.getCode());
        completedQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long completedAppointments = appointmentRecordMapper.selectCount(completedQueryWrapper);
        vo.setCompletedAppointments(completedAppointments);

        // 5. 统计已取消预约数
        QueryWrapper<AppointmentRecord> cancelledQueryWrapper = new QueryWrapper<>();
        cancelledQueryWrapper.eq("appointment_status", AppointmentStatusEnum.CANCELLED.getCode());
        cancelledQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long cancelledAppointments = appointmentRecordMapper.selectCount(cancelledQueryWrapper);
        vo.setCancelledAppointments(cancelledAppointments);

        // 6. 统计今日新增预约数
        QueryWrapper<AppointmentRecord> todayQueryWrapper = new QueryWrapper<>();
        todayQueryWrapper.eq("appointment_time", LocalDate.now());
        todayQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long todayAppointments = appointmentRecordMapper.selectCount(todayQueryWrapper);
        vo.setTodayAppointments(todayAppointments);

        // 7. 统计总接种点数
        QueryWrapper<VaccinationSite> siteQueryWrapper = new QueryWrapper<>();
        siteQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long totalSites = vaccinationSiteMapper.selectCount(siteQueryWrapper);
        vo.setTotalVaccinationSites(totalSites);

        // 8. 统计总疫苗种类数
        QueryWrapper<Vaccine> vaccineQueryWrapper = new QueryWrapper<>();
        vaccineQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long totalVaccines = vaccineMapper.selectCount(vaccineQueryWrapper);
        vo.setTotalVaccineTypes(totalVaccines);

        // 9. 统计总库存数量
        QueryWrapper<Inventory> inventoryQueryWrapper = new QueryWrapper<>();
        inventoryQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        List<Inventory> inventoryList = inventoryMapper.selectList(inventoryQueryWrapper);
        long totalInventory = 0;
        for (Inventory inventory : inventoryList) {
            totalInventory += inventory.getCount();
        }
        vo.setTotalInventoryCount(totalInventory);

        return vo;
    }

    /**
     * 获取预约趋势统计
     */
    @Override
    public List<AppointmentTrendVO> getAppointmentTrend(LocalDate startDate, LocalDate endDate) {
        // 验证日期范围
        if (startDate.isAfter(endDate)) {
            throw new CommonException(CommonErrorCode.INVALID_PARAMETER);
        }

        // 查询日期范围内的所有预约
        QueryWrapper<AppointmentRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("appointment_time", startDate);
        queryWrapper.le("appointment_time", endDate);
        queryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        queryWrapper.orderByAsc("appointment_time");
        List<AppointmentRecord> records = appointmentRecordMapper.selectList(queryWrapper);

        // 按日期分组统计
        Map<LocalDate, AppointmentTrendVO> trendMap = new HashMap<>();
        
        // 初始化日期范围内的所有日期
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            AppointmentTrendVO vo = new AppointmentTrendVO();
            vo.setDate(currentDate);
            vo.setAppointmentCount(0);
            vo.setCompletedCount(0);
            vo.setCancelledCount(0);
            trendMap.put(currentDate, vo);
            currentDate = currentDate.plusDays(1);
        }

        // 统计每天的数据
        for (AppointmentRecord record : records) {
            LocalDate date = record.getAppointmentTime();
            AppointmentTrendVO vo = trendMap.get(date);
            if (vo != null) {
                vo.setAppointmentCount(vo.getAppointmentCount() + 1);
                
                if (record.getAppointmentStatus().equals(AppointmentStatusEnum.COMPLETED.getCode())) {
                    vo.setCompletedCount(vo.getCompletedCount() + 1);
                } else if (record.getAppointmentStatus().equals(AppointmentStatusEnum.CANCELLED.getCode())) {
                    vo.setCancelledCount(vo.getCancelledCount() + 1);
                }
            }
        }

        // 转换为列表并按日期排序
        List<AppointmentTrendVO> result = new ArrayList<>(trendMap.values());
        result.sort((a, b) -> a.getDate().compareTo(b.getDate()));

        return result;
    }

    /**
     * 获取特定接种点的统计数据
     */
    @Override
    public SiteStatisticsVO getSiteStatistics(Integer siteId) {
        // 1. 查询接种点信息
        VaccinationSite site = vaccinationSiteMapper.selectById(siteId);
        if (site == null || site.getDelFlg().equals(DelFlgEnum.DELETED.getCode())) {
            throw new CommonException(CommonErrorCode.NOT_FOUND);
        }

        SiteStatisticsVO vo = new SiteStatisticsVO();
        vo.setSiteId(site.getId());
        vo.setSiteName(site.getName());
        vo.setSiteAddress(site.getAddress());

        // 2. 统计总预约数
        QueryWrapper<AppointmentRecord> totalQueryWrapper = new QueryWrapper<>();
        totalQueryWrapper.eq("vaccination_site_id", siteId);
        totalQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long totalAppointments = appointmentRecordMapper.selectCount(totalQueryWrapper);
        vo.setTotalAppointments(totalAppointments.intValue());

        // 3. 统计待接种数
        QueryWrapper<AppointmentRecord> pendingQueryWrapper = new QueryWrapper<>();
        pendingQueryWrapper.eq("vaccination_site_id", siteId);
        pendingQueryWrapper.eq("appointment_status", AppointmentStatusEnum.APPOINTED.getCode());
        pendingQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long pendingAppointments = appointmentRecordMapper.selectCount(pendingQueryWrapper);
        vo.setPendingAppointments(pendingAppointments.intValue());

        // 4. 统计已完成数
        QueryWrapper<AppointmentRecord> completedQueryWrapper = new QueryWrapper<>();
        completedQueryWrapper.eq("vaccination_site_id", siteId);
        completedQueryWrapper.eq("appointment_status", AppointmentStatusEnum.COMPLETED.getCode());
        completedQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long completedAppointments = appointmentRecordMapper.selectCount(completedQueryWrapper);
        vo.setCompletedAppointments(completedAppointments.intValue());

        // 5. 统计已取消数
        QueryWrapper<AppointmentRecord> cancelledQueryWrapper = new QueryWrapper<>();
        cancelledQueryWrapper.eq("vaccination_site_id", siteId);
        cancelledQueryWrapper.eq("appointment_status", AppointmentStatusEnum.CANCELLED.getCode());
        cancelledQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long cancelledAppointments = appointmentRecordMapper.selectCount(cancelledQueryWrapper);
        vo.setCancelledAppointments(cancelledAppointments.intValue());

        // 6. 统计今日预约数
        QueryWrapper<AppointmentRecord> todayQueryWrapper = new QueryWrapper<>();
        todayQueryWrapper.eq("vaccination_site_id", siteId);
        todayQueryWrapper.eq("appointment_time", LocalDate.now());
        todayQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Long todayAppointments = appointmentRecordMapper.selectCount(todayQueryWrapper);
        vo.setTodayAppointments(todayAppointments.intValue());

        // 7. 统计疫苗种类数
        QueryWrapper<Inventory> vaccineTypeQueryWrapper = new QueryWrapper<>();
        vaccineTypeQueryWrapper.eq("vaccination_site_id", siteId);
        vaccineTypeQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        vaccineTypeQueryWrapper.select("DISTINCT vaccine_id");
        Long vaccineTypeCount = inventoryMapper.selectCount(vaccineTypeQueryWrapper);
        vo.setVaccineTypeCount(vaccineTypeCount.intValue());

        // 8. 统计总库存数
        QueryWrapper<Inventory> inventoryQueryWrapper = new QueryWrapper<>();
        inventoryQueryWrapper.eq("vaccination_site_id", siteId);
        inventoryQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        List<Inventory> inventoryList = inventoryMapper.selectList(inventoryQueryWrapper);
        int totalInventory = 0;
        int lowStockAlerts = 0;
        for (Inventory inventory : inventoryList) {
            totalInventory += inventory.getCount();
            // 低库存预警阈值为10
            if (inventory.getCount() < 10) {
                lowStockAlerts++;
            }
        }
        vo.setTotalInventory(totalInventory);
        vo.setLowStockAlerts(lowStockAlerts);

        return vo;
    }
}

